/**
 * 
 */
package com.lanswon.qzsmk.authen;

import java.util.List;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import ch.qos.logback.classic.Logger;

import com.lanswon.qzsmk.dao.OrgMapper;
import com.lanswon.qzsmk.dao.RolePrivilegeMapper;
import com.lanswon.qzsmk.dao.SysPermissionMapper;
import com.lanswon.qzsmk.dao.TellerMapper;
import com.lanswon.qzsmk.dao.UserMapper;
import com.lanswon.qzsmk.dao.UserOrgAdminMapper;
import com.lanswon.qzsmk.dao.UserRoleAdminMapper;
import com.lanswon.qzsmk.model.ActiveUser;
import com.lanswon.qzsmk.model.Org;
import com.lanswon.qzsmk.model.SysPermission;
import com.lanswon.qzsmk.model.User;

/**
 * @author sun
 *
 */
public class CustomRealm extends AuthorizingRealm {

	@Autowired
	UserMapper um;
	
	@Autowired
	UserRoleAdminMapper uram;
	
	
	@Autowired
	SysPermissionMapper spm;
	
	@Autowired
	RolePrivilegeMapper rpm;
	
	@Autowired
	OrgMapper om;
	
	@Autowired
	TellerMapper tm;
	
	@Autowired
	UserOrgAdminMapper uoam;
	
	private static Logger logger = (Logger) LoggerFactory.getLogger(CustomRealm.class);

	
	// 设置Realm名称  
    @Override  
    public void setName(String name) {  
        super.setName("CustomRealm");  
    }  
    
    
 // 支持UsernamePasswordToken  
    @Override  
    public boolean supports(AuthenticationToken token) {  
        return token instanceof UsernamePasswordToken;  
    }  
	
 // 用于授权  
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		 Long start = System.currentTimeMillis();
		
		 //获取身份信息  
        ActiveUser activeUser = (ActiveUser) principals.getPrimaryPrincipal();  
        //用户id  
        Integer userId = activeUser.getUserId();  
        logger.debug("用户登录名[{}]",activeUser.getLoginName());
          
        //将权限信息封装为AuthorizationInfo  
        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();  
        //基于资源权限的访问控制  
        List<SysPermission> lsp =  spm.querySysPermissionByUserId(userId);
        for(SysPermission sp:lsp){
        	simpleAuthorizationInfo.addStringPermission(sp.getPercode()); 
        }
        
        
        // 如果基于角色进行访问控制  
        // for (String role : roles) {  
        // simpleAuthorizationInfo.addRole(role);  
        // }  
          logger.debug("时间差【{}】",System.currentTimeMillis()-start);
        return simpleAuthorizationInfo;  
    }  

	// 用于认证  
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		 // 从token中获取用户身份信息  
        String loginName = (String) token.getPrincipal();  
        String password = new String((char[])token.getCredentials());
        
        ByteSource credentialsSalt = ByteSource.Util.bytes(loginName);
	    Object result = new SimpleHash("MD5",password,credentialsSalt,1024);  

        logger.debug("登录名[{}],密码[{}]",loginName,password);
        User u =um.queryUserByLoginName(loginName);
        if(u == null){
        	throw new UnknownAccountException();
        }else if(!u.getLoginPassword().equals(result.toString())){
        	 throw new IncorrectCredentialsException();
        }
        // 根据用户id从数据库中取出菜单  
        // ...先使用静态数据  
        
//        List<SysPermission> menus = new ArrayList<SysPermission>();  
        
        Org org=null;
        try{
        	org =  om.queryOrgById(uoam.queryUserOrgAdminByUserId(u.getUserId()).getOrgId());
        }catch(Exception exception){
        	exception.printStackTrace();
        	throw new LockedAccountException();
        }
        
        // 构建用户身份信息  
        ActiveUser activeUser = new ActiveUser();  
        activeUser.setUserNo(u.getUserNo());
        activeUser.setUserId(u.getUserId());  
        activeUser.setUserName(u.getUserName()); 
        activeUser.setLoginName(loginName);
        
        activeUser.setBranchName(org.getOrgName());
        activeUser.setBranchNo(org.getOrgNo().toString());
//        activeUser.setLoginPassword(result.toString());
        activeUser.setMenus(null);  
        // 返回认证信息由父类AuthenticationRealm进行认证  

        SimpleAuthenticationInfo simpleAuthenticationInfo = new SimpleAuthenticationInfo(activeUser, result.toString(), credentialsSalt, getName()); 
        return simpleAuthenticationInfo;  
	}
	
	 // 清除缓存  
    public void clearCached() {  
        PrincipalCollection principals = SecurityUtils.getSubject().getPrincipals();  
        super.clearCache(principals);  
    }  
    
    /** 
     * 将一些数据放到ShiroSession中,以便于其它地方使用 
     * @see 比如Controller,使用时直接用HttpSession.getAttribute(key)就可以取到 
     */  
//    private void setSession(Object key, Object value){  
//        Subject currentUser = SecurityUtils.getSubject();  
//        if(null != currentUser){  
//            Session session = currentUser.getSession();  
//           logger.debug("Session默认超时时间为[{}]毫秒",session.getTimeout());  
//            if(null != session){  
//                session.setAttribute(key, value);  
//            }  
//        }  
//    }  

}
